import React, { useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import './Earth3D.css';
import { 
  LatLngPoint, 
  LatLngRect, 
  LocationPoint, 
  DetectionPoint 
} from '../types/earth';
import { 
  rectToPolygon,
  getCorrectLngRange,
  rectIntersects,
  pointIntersectsRect,
  getEarthScreenDiameterPrecise,
  getVisibleArcBySampling,
  getMouseRaycastForModel,
  latLngToModelSurface
} from '../utils/earthUtils';

interface GLBRendererProps {
  modelUrl: string; // GLB模型文件URL
  radius: number; // 星体半径（用于计算缩放）
  rects?: LatLngRect[];
  locationPoints?: LocationPoint[];
  detectionPoints?: DetectionPoint[];
  onHover?: (coord: LatLngPoint | null) => void;
  onClick?: (coord: LatLngPoint | null) => void;
  onLocationHover?: (location: LocationPoint | null) => void;
  onLocationClick?: (location: LocationPoint | null) => void;
  onDetectionPointHover?: (detectionPoint: DetectionPoint | null) => void;
  onDetectionPointClick?: (detectionPoint: DetectionPoint | null) => void;
  onSelectionChange?: (selectionRect: LatLngRect | null) => void;
  onSelectionEnd?: (selectionRect: LatLngRect | null, intersectingRects: LatLngRect[], intersectingDetectionPoints: DetectionPoint[]) => void;
  externalSelection?: LatLngRect | null;
  simulatedMetaKey?: boolean;
}

// 定义暴露的方法接口
export interface GLBRendererRef {
  zoomIn: () => void;
  zoomOut: () => void;
  resetView: () => void;
  getCameraZ: () => number;
  setCameraZ: (z: number) => void;
  enterSelectionMode: () => void;
  exitSelectionMode: () => void;
  clearSelection: () => void;
}

const GLBRenderer = forwardRef<GLBRendererRef, GLBRendererProps>(({ 
  modelUrl,
  radius,
  rects: propsRects = [],
  locationPoints = [],
  detectionPoints = [],
  onHover,
  onClick,
  onLocationHover,
  onLocationClick,
  onDetectionPointHover,
  onDetectionPointClick,
  onSelectionChange,
  onSelectionEnd,
  externalSelection,
  simulatedMetaKey = false
}, ref) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const sceneRef = useRef<THREE.Scene | null>(null);
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null);
  const modelRef = useRef<THREE.Group | null>(null);
  const markersRef = useRef<THREE.Group | null>(null);
  const raycasterRef = useRef<THREE.Raycaster>(new THREE.Raycaster());
  const mouseRef = useRef<THREE.Vector2>(new THREE.Vector2());
  const modelRadiusRef = useRef<number>(1);
  
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectionPoints, setSelectionPoints] = useState<[LatLngPoint, LatLngPoint] | null>(null);
  const [selectionClickCount, setSelectionClickCount] = useState(0);
  const [selectionLine, setSelectionLine] = useState<THREE.Line | null>(null);
  
  // Hover焦点相关状态
  const [hoverFocus, setHoverFocus] = useState<{ lat: number; lng: number; point: THREE.Vector3 } | null>(null);
  const [focusMarker, setFocusMarker] = useState<THREE.Mesh | null>(null);
  
  // 黄色hover点相关状态
  const [yellowHoverPoint, setYellowHoverPoint] = useState<{ lat: number; lng: number; point: THREE.Vector3 } | null>(null);
  const [yellowMarker, setYellowMarker] = useState<THREE.Mesh | null>(null);
  const rectLinesRef = useRef<THREE.Line[]>([]);
  const rectLabelsRef = useRef<THREE.Sprite[]>([]);
  
  // 拖动旋转相关状态
  const [isDragging, setIsDragging] = useState(false);
  const [hasDragged, setHasDragged] = useState(false);
  const [lastMouse, setLastMouse] = useState({ x: 0, y: 0 });
  const [lastRotation, setLastRotation] = useState({ x: 0, y: 0 });
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
  const [inertia, setInertia] = useState({ vx: 0, vy: 0 });
  const [lastMove, setLastMove] = useState({ x: 0, y: 0, t: 0 });
  const DRAG_CLICK_BUFFER = 5;

  // 暴露给父组件的方法
  useImperativeHandle(ref, () => ({
    zoomIn: () => {
      if (cameraRef.current) {
        const distance = cameraRef.current.position.length();
        cameraRef.current.position.normalize().multiplyScalar(distance * 0.8);
      }
    },
    zoomOut: () => {
      if (cameraRef.current) {
        const distance = cameraRef.current.position.length();
        cameraRef.current.position.normalize().multiplyScalar(distance * 1.2);
      }
    },
    resetView: () => {
      if (cameraRef.current && modelRef.current) {
        const box = new THREE.Box3().setFromObject(modelRef.current);
        const size = box.getSize(new THREE.Vector3());
        const maxDim = Math.max(size.x, size.y, size.z);
        const fov = cameraRef.current.fov * (Math.PI / 180);
        const distance = Math.abs(maxDim / Math.sin(fov / 2)) * 1.5;
        
        cameraRef.current.position.set(distance, distance, distance);
        cameraRef.current.lookAt(0, 0, 0);
        
        // 重置模型旋转
        modelRef.current.rotation.x = 0;
        modelRef.current.rotation.y = 0;
        // 清除惯性
        setInertia({ vx: 0, vy: 0 });
      }
    },
    getCameraZ: () => {
      return cameraRef.current?.position.length() || 0;
    },
    setCameraZ: (z: number) => {
      if (cameraRef.current) {
        const direction = cameraRef.current.position.clone().normalize();
        cameraRef.current.position.copy(direction.multiplyScalar(z));
      }
    },
    enterSelectionMode: () => {
      // 这个方法现在由父组件通过simulatedMetaKey控制
    },
    exitSelectionMode: () => {
      setSelectionPoints(null);
      setSelectionClickCount(0);
    },
    clearSelection: () => {
      setSelectionPoints(null);
      setSelectionClickCount(0);
      clearSelectionLine();
      onSelectionChange?.(null);
    }
  }));

  // 初始化Three.js场景
  const initScene = () => {
    if (!containerRef.current) return;

    const container = containerRef.current;
    // 确保容器有高度，如果没有则使用默认值
    const width = container.clientWidth || window.innerWidth;
    const height = container.clientHeight || window.innerHeight || 400;

    // 创建场景
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x000011);
    sceneRef.current = scene;

    // 创建相机
    const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
    camera.position.set(0, 0, 5); // 正对模型，保证水平拖拽更直观
    cameraRef.current = camera;

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(width, height);
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    rendererRef.current = renderer;


    // 添加光源
    const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
    scene.add(ambientLight);

    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
    // 初始给一个固定位置，待模型加载后基于模型半径再调整
    directionalLight.position.set(5, 5, 5);
    directionalLight.castShadow = true;
    directionalLight.shadow.mapSize.width = 2048;
    directionalLight.shadow.mapSize.height = 2048;
    scene.add(directionalLight);

    // 创建标记组（先挂到场景，模型加载后再挂到模型，使其跟随旋转）
    const markers = new THREE.Group();
    markersRef.current = markers;
    scene.add(markers);

    container.appendChild(renderer.domElement);
  };

  // 加载GLB模型
  const loadModel = async () => {
    if (!sceneRef.current) return;

    try {
      setIsLoading(true);
      setError(null);

      const loader = new GLTFLoader();
      const gltf = await loader.loadAsync(modelUrl);
      
      const model = gltf.scene;
      modelRef.current = model;

      // 计算模型边界并调整大小
      const box = new THREE.Box3().setFromObject(model);
      const size = box.getSize(new THREE.Vector3());
      const maxDim = Math.max(size.x, size.y, size.z);
      // 使用固定缩放比例，让模型大小适中
      const scale = 1; // 保持原始大小
      model.scale.setScalar(scale);

      // 居中模型
      const center = box.getCenter(new THREE.Vector3());
      model.position.sub(center.multiplyScalar(scale));

      // 记录模型半径（基于边界盒）
      modelRadiusRef.current = (maxDim * scale) / 2;

      // 添加材质和阴影
      model.traverse((child: any) => {
        if (child instanceof THREE.Mesh) {
          child.castShadow = true;
          child.receiveShadow = true;
          
          // 设置模型透明度
          if (child.material) {
            if (Array.isArray(child.material)) {
              // 处理多材质情况
              child.material.forEach((material: any) => {
                material.transparent = true;
                material.opacity = 0.3;
              });
            } else {
              // 处理单材质情况
              child.material.transparent = true;
              child.material.opacity = 0.3;
            }
          }
        }
      });

      sceneRef.current.add(model);

      // 将标记组挂到模型上，使其随模型一起旋转
      if (markersRef.current) {
        // 先从场景中移除再添加到模型
        if (sceneRef.current && markersRef.current.parent === sceneRef.current) {
          sceneRef.current.remove(markersRef.current);
        }
        model.add(markersRef.current);
      }

      // 调整相机位置
      if (cameraRef.current) {
        const fov = cameraRef.current.fov * (Math.PI / 180);
        const distance = Math.abs(maxDim * scale / Math.sin(fov / 2)) * 1.5;
        cameraRef.current.position.set(0, 0, distance);
        cameraRef.current.lookAt(0, 0, 0);
      }

      // 基于模型半径调整主光源位置
      if (sceneRef.current) {
        const dirLight = sceneRef.current.children.find(
          (obj: THREE.Object3D) => obj instanceof THREE.DirectionalLight
        ) as THREE.DirectionalLight | undefined;
        if (dirLight) {
          const r = modelRadiusRef.current * 2;
          dirLight.position.set(r, r, r);
        }
      }

      // 初始渲染：地点与rects
      createLocationMarkers();
      renderRects();

      setIsLoading(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load GLB model');
      setIsLoading(false);
    }
  };

  // 创建位置标记
  const createLocationMarkers = () => {
    if (!markersRef.current || !modelRef.current) return;

    // 清除现有标记
    markersRef.current.clear();

    locationPoints.forEach((location) => {
      const label = createLocationLabel(location);
      if (label) {
        (label as any).userData = { type: 'location', data: location };
        markersRef.current!.add(label);
      } else {
        const marker = createMarker(location.center_latitude, location.center_longitude, 0x00ff00, 0.1);
        if (marker) {
          marker.userData = { type: 'location', data: location };
          markersRef.current!.add(marker);
        }
      }
    });

    detectionPoints.forEach((point) => {
      const marker = createMarker(point.center_latitude, point.center_longitude, 0xff0000, 0.1);
      if (marker) {
        marker.userData = { type: 'detection', data: point };
        markersRef.current!.add(marker);
      }
    });
  };

  // 文本纹理
  const createTextTexture = (text: string, options: { hasShadow?: boolean; hasStroke?: boolean; strokeColor?: string; strokeWidth?: number } = {}) => {
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    if (!context) return null;
    canvas.width = 256;
    canvas.height = 96;
    context.font = 'bold 28px Arial';
    context.fillStyle = '#ffffff';
    context.textAlign = 'center';
    context.textBaseline = 'middle';
    if (options.hasShadow) {
      (context as any).shadowColor = 'rgba(0, 0, 0, 0.8)';
      (context as any).shadowBlur = 4;
      (context as any).shadowOffsetX = 2;
      (context as any).shadowOffsetY = 2;
    }
    if (options.hasStroke) {
      context.strokeStyle = options.strokeColor || '#000000';
      context.lineWidth = options.strokeWidth || 3;
    }
    const x = canvas.width / 2;
    const y = canvas.height / 2;
    if (options.hasStroke) { context.strokeText(text, x, y); }
    context.fillText(text, x, y);
    const texture = new THREE.CanvasTexture(canvas);
    texture.needsUpdate = true;
    return texture;
  };

  // 地点文字标签
  const createLocationLabel = (location: LocationPoint) => {
    if (!modelRef.current) return null;
    const texture = createTextTexture(location.name, { hasShadow: true });
    if (!texture) return null;
    const material = new THREE.SpriteMaterial({ map: texture, transparent: true, depthTest: false, depthWrite: false });
    const sprite = new THREE.Sprite(material);
    sprite.scale.set(1, 0.4, 1);
    const surfacePoint = latLngToModelSurface(location.center_latitude, location.center_longitude, modelRef.current.children[0] as THREE.Mesh);
    const localPoint = modelRef.current.worldToLocal(surfacePoint.clone());
    sprite.position.copy(localPoint);
    return sprite;
  };

  // 渲染rect边框与文字
  const renderRects = () => {
    if (!modelRef.current) return;
    // 清理旧线
    rectLinesRef.current.forEach(line => {
      modelRef.current!.remove(line);
      if (line.geometry) line.geometry.dispose();
      if (line.material) (line.material as any).dispose?.();
    });
    rectLinesRef.current = [];
    // 清理旧label
    rectLabelsRef.current.forEach(label => {
      modelRef.current!.remove(label);
      if ((label.material as any)?.map) (label.material as any).map.dispose?.();
      (label.material as any).dispose?.();
    });
    rectLabelsRef.current = [];

    (propsRects || []).forEach(rect => {
      const polygon = rectToPolygon(rect, 2);
      const borderPoints = polygon.points.map(pt => {
        const surfacePoint = latLngToModelSurface(pt.lat, pt.lng, modelRef.current!.children[0] as THREE.Mesh);
        return modelRef.current!.worldToLocal(surfacePoint.clone());
      });
      if (borderPoints.length > 0) borderPoints.push(borderPoints[0].clone());
      const geometry = new THREE.BufferGeometry().setFromPoints(borderPoints);
      const material = new THREE.LineBasicMaterial({ color: 0x00ff00, linewidth: 2, transparent: true, opacity: 1.0, depthTest: false, depthWrite: false });
      const line = new THREE.Line(geometry, material);
      modelRef.current.add(line);
      rectLinesRef.current.push(line);

      if (rect.name) {
        const centerLat = (rect.minLat + rect.maxLat) / 2;
        const centerLng = (rect.minLng + rect.maxLng) / 2;
        const textTex = createTextTexture(rect.name, { hasStroke: true });
        if (textTex) {
          const mat = new THREE.SpriteMaterial({ map: textTex, transparent: true, depthTest: false, depthWrite: false });
          const sprite = new THREE.Sprite(mat);
          sprite.scale.set(1, 0.4, 1);
          const surfacePoint = latLngToModelSurface(centerLat, centerLng, modelRef.current.children[0] as THREE.Mesh);
          const localPoint = modelRef.current.worldToLocal(surfacePoint.clone());
          sprite.position.copy(localPoint);
          modelRef.current.add(sprite);
          rectLabelsRef.current.push(sprite);
        }
      }
    });
  };

  // 当 rects 或模型变化时重新渲染
  useEffect(() => {
    renderRects();
  }, [propsRects, modelRef.current]);

  // 创建标记
  const createMarker = (lat: number, lng: number, color: number, size: number) => {
    if (!modelRef.current) return null;

    // 使用 latLngToModelSurface 将经纬度转换为模型表面坐标
    const surfacePoint = latLngToModelSurface(lat, lng, modelRef.current.children[0] as THREE.Mesh);
    
    // 将世界坐标转换为模型本地坐标
    const localPoint = modelRef.current.worldToLocal(surfacePoint.clone());

    const geometry = new THREE.SphereGeometry(size, 8, 6);
    const material = new THREE.MeshBasicMaterial({ color });
    const marker = new THREE.Mesh(geometry, material);
    
    marker.position.copy(localPoint);
    return marker;
  };

  // 创建焦点标记（红点）
  const createFocusMarker = (point: THREE.Vector3) => {
    if (!markersRef.current || !modelRef.current) return null;

    // 创建红点标记，稍微突出模型表面
    const geometry = new THREE.SphereGeometry(0.05, 16, 16);
    const material = new THREE.MeshBasicMaterial({ 
      color: 0xff0000,
      transparent: true,
      opacity: 0.8
    });
    const marker = new THREE.Mesh(geometry, material);
    
    // 将世界坐标转换为模型本地坐标
    const localPoint = modelRef.current.worldToLocal(point.clone());
    marker.position.copy(localPoint);
    
    return marker;
  };

  // 创建黄色hover标记
  const createYellowMarker = (lat: number, lng: number) => {
    if (!markersRef.current || !modelRef.current) return null;

    // 使用 latLngToModelSurface 将经纬度转换为模型表面坐标
    const surfacePoint = latLngToModelSurface(lat, lng, modelRef.current.children[0] as THREE.Mesh);
    
    // 将世界坐标转换为模型本地坐标
    const localPoint = modelRef.current.worldToLocal(surfacePoint.clone());

    // 创建黄色球体标记
    const geometry = new THREE.SphereGeometry(0.08, 16, 16);
    const material = new THREE.MeshBasicMaterial({ 
      color: 0xffff00, // 黄色
      transparent: true,
      opacity: 0.5
    });
    const marker = new THREE.Mesh(geometry, material);
    
    marker.position.copy(localPoint);
    return marker;
  };

  // 更新焦点标记
  const updateFocusMarker = (focus: { lat: number; lng: number; point: THREE.Vector3 } | null) => {
    // 清除现有焦点标记
    if (focusMarker && markersRef.current) {
      markersRef.current.remove(focusMarker);
      focusMarker.geometry.dispose();
      if (Array.isArray(focusMarker.material)) {
        focusMarker.material.forEach((m: any) => m.dispose());
      } else {
        focusMarker.material.dispose();
      }
      setFocusMarker(null);
    }

    // 创建新的焦点标记
    if (focus && markersRef.current) {
      const newMarker = createFocusMarker(focus.point);
      if (newMarker) {
        markersRef.current.add(newMarker);
        setFocusMarker(newMarker);
      }
    }
  };

  // 更新黄色hover标记
  const updateYellowMarker = (hoverPoint: { lat: number; lng: number; point: THREE.Vector3 } | null) => {
    // 清除现有黄色标记
    if (yellowMarker && markersRef.current) {
      markersRef.current.remove(yellowMarker);
      yellowMarker.geometry.dispose();
      if (Array.isArray(yellowMarker.material)) {
        yellowMarker.material.forEach((m: any) => m.dispose());
      } else {
        yellowMarker.material.dispose();
      }
      setYellowMarker(null);
    }

    // 创建新的黄色标记
    if (hoverPoint && markersRef.current) {
      const newMarker = createYellowMarker(hoverPoint.lat, hoverPoint.lng);
      if (newMarker) {
        markersRef.current.add(newMarker);
        setYellowMarker(newMarker);
      }
    }
  };

  // 获取鼠标点击的经纬度坐标
  const getMouseLatLng = (event: MouseEvent): LatLngPoint | null => {
    if (!containerRef.current || !cameraRef.current || !rendererRef.current || !modelRef.current) {
      return null;
    }

    const hit = getMouseRaycastForModel(event, cameraRef.current, rendererRef.current, modelRef.current.children[0]);
    if (hit) {
      return { lat: hit.lat, lng: hit.lng };
    }
    
    return null;
  };

  // 渲染选区线框
  const renderSelection = () => {
    if (!modelRef.current) return;
    
    // 清理旧线框
    if (selectionLine) {
      // 从模型中移除线条
      if (modelRef.current) {
        modelRef.current.remove(selectionLine);
      }
      // 清理几何体和材质
      selectionLine.geometry.dispose();
      if (Array.isArray(selectionLine.material)) {
        selectionLine.material.forEach((m: any) => m.dispose());
      } else {
        selectionLine.material.dispose();
      }
      setSelectionLine(null);
    }

    if (selectionPoints && selectionPoints.length === 2) {
      // 画矩形线框
      const [p1, p2] = selectionPoints;
      // 使用新的函数处理经度范围，考虑跨越-180到180度的情况
      const lngRange = getCorrectLngRange(p1.lng, p2.lng);
      console.log('lngRange', p1, p2);
      const rect = {
        minLat: Math.min(p1.lat, p2.lat),
        maxLat: Math.max(p1.lat, p2.lat),
        minLng: lngRange.minLng,
        maxLng: lngRange.maxLng
      };
      const polygon = rectToPolygon(rect, 2);
      console.log(polygon)
      // 调试：输出选区信息
      
      // 使用 latLngToModelSurface 将多边形点投影到模型表面
      const borderPoints = polygon.points.map(pt => {
        const surfacePoint = latLngToModelSurface(pt.lat, pt.lng, modelRef.current!.children[0] as THREE.Mesh);
        // 将世界坐标转换为模型本地坐标
        return modelRef.current!.worldToLocal(surfacePoint.clone());
      });

      // 创建更明显的线条
      const geometry = new THREE.BufferGeometry().setFromPoints(borderPoints);
      const material = new THREE.LineBasicMaterial({ 
        color: 0xff0000, // 改为红色，更明显
        linewidth: 10,   // 进一步增加线条宽度
        transparent: true,
        opacity: 1.0,   // 完全不透明
        depthTest: false, // 禁用深度测试，确保线条始终可见
        depthWrite: false // 禁用深度写入
      });
      const line = new THREE.Line(geometry, material);
      
      // 调试：输出线条信息
      
      // 将线条添加到模型，使其跟随模型旋转
      if (modelRef.current) {
        modelRef.current.add(line);
      }
      setSelectionLine(line);
      
    }
  };

  // 清除选区线框
  const clearSelectionLine = () => {
    if (selectionLine) {
      // 从模型中移除线条
      if (modelRef.current) {
        modelRef.current.remove(selectionLine);
      }
      // 清理几何体和材质
      selectionLine.geometry.dispose();
      if (Array.isArray(selectionLine.material)) {
        selectionLine.material.forEach((m: any) => m.dispose());
      } else {
        selectionLine.material.dispose();
      }
      setSelectionLine(null);
    }
  };

  // 处理鼠标按下
  const handleMouseDown = (event: MouseEvent) => {
    if (!containerRef.current || !cameraRef.current || !rendererRef.current || !modelRef.current) return;
    
    setIsDragging(true);
    setHasDragged(false);
    setLastMouse({ x: event.clientX, y: event.clientY });
    setDragStart({ x: event.clientX, y: event.clientY });
    setLastRotation({
      x: modelRef.current.rotation.x,
      y: modelRef.current.rotation.y
    });
    setLastMove({ x: event.clientX, y: event.clientY, t: Date.now() });
    setInertia({ vx: 0, vy: 0 });
  };

  // 处理鼠标移动
  const handleMouseMove = (event: MouseEvent) => {
    if (!containerRef.current || !cameraRef.current || !rendererRef.current) return;

    const rect = containerRef.current.getBoundingClientRect();
    mouseRef.current.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouseRef.current.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

    // 拖动判定
    if (isDragging && modelRef.current) {
      const dx = event.clientX - lastMouse.x;
      const dy = event.clientY - lastMouse.y;
      if (!hasDragged) {
        const totalDx = event.clientX - dragStart.x;
        const totalDy = event.clientY - dragStart.y;
        const dist = Math.sqrt(totalDx * totalDx + totalDy * totalDy);
        if (dist > DRAG_CLICK_BUFFER) { 
          setHasDragged(true); 
        }
      }
      if (hasDragged) {
        // 只处理模型旋转
        const earthScreenDiameter = getEarthScreenDiameterPrecise(cameraRef.current, rendererRef.current);
        const visibleArc = getVisibleArcBySampling(cameraRef.current, rendererRef.current);
        const deltaTheta = (dx / earthScreenDiameter) * visibleArc;
        const deltaPhi = (dy / earthScreenDiameter) * visibleArc;
        modelRef.current.rotation.y = lastRotation.y + deltaTheta;
        modelRef.current.rotation.x = Math.max(-Math.PI/2, Math.min(Math.PI/2, lastRotation.x + deltaPhi));
        // 记录速度
        const now = Date.now();
        const dt = now - lastMove.t;
        if (dt > 0) {
          setInertia({
            vx: (event.clientX - lastMove.x) / dt,
            vy: (event.clientY - lastMove.y) / dt
          });
        }
        setLastMove({ x: event.clientX, y: event.clientY, t: now });
        return;
      }
    }

    // 选区模式下，第一次点后移动鼠标实时渲染选区和相交高亮
    if (simulatedMetaKey && selectionPoints && selectionClickCount === 1) {
      const hit = getMouseLatLng(event);
      if (hit) {
        console.log('hit', selectionPoints[0], hit);
        const previewSelectionPoints: [LatLngPoint, LatLngPoint] = [selectionPoints[0], hit];
        setSelectionPoints(previewSelectionPoints);
        // renderSelection() 会通过useEffect自动调用，不需要手动调用
        // 实时显示选区坐标信息
        if (onSelectionChange) {
          const [start, end] = previewSelectionPoints;
          const lngRange = getCorrectLngRange(start.lng, end.lng);
          const selectionRect: LatLngRect = {
            minLat: Math.min(start.lat, end.lat),
            maxLat: Math.max(start.lat, end.lat),
            minLng: lngRange.minLng,
            maxLng: lngRange.maxLng
          };
          onSelectionChange(selectionRect);
        }
      }
      return;
    }

    // 射线检测
    if (modelRef.current && cameraRef.current && rendererRef.current) {
      const hit = getMouseRaycastForModel(event, cameraRef.current, rendererRef.current, modelRef.current.children[0]);
      if (hit) {
        // 仅当坐标有显著变化时才触发外部onHover，避免高频无意义更新
        const newCoord = { lat: hit.lat, lng: hit.lng };
        const last = hoverFocus ? { lat: hoverFocus.lat, lng: hoverFocus.lng } : null;
        const changed = !last || Math.abs(last.lat - newCoord.lat) > 1e-4 || Math.abs(last.lng - newCoord.lng) > 1e-4;
        if (changed) {
          onHover?.(newCoord);
        }
        // 更新hover焦点
        setHoverFocus(hit);
        // 更新黄色hover点
        setYellowHoverPoint(hit);
      } else {
        if (hoverFocus !== null) {
          onHover?.(null);
        }
        // 清除hover焦点
        setHoverFocus(null);
        // 清除黄色hover点
        setYellowHoverPoint(null);
      }
    }

    // 检测标记悬停
    if (markersRef.current) {
      const intersects = raycasterRef.current.intersectObjects(markersRef.current.children, true);
      if (intersects.length > 0) {
        const marker = intersects[0].object;
        const userData = marker.userData;
        if (userData.type === 'location') {
          onLocationHover?.(userData.data);
        } else if (userData.type === 'detection') {
          onDetectionPointHover?.(userData.data);
        }
      } else {
        onLocationHover?.(null);
        onDetectionPointHover?.(null);
      }
    }
  };

  // 处理鼠标滚轮缩放
  const handleWheel = (event: WheelEvent) => {
    if (!cameraRef.current) return;
    
    event.preventDefault();
    const zoomSpeed = 0.1;
    const deltaY = event.deltaY;
    
    // 计算新的相机距离
    const currentDistance = cameraRef.current.position.length();
    const newDistance = currentDistance + deltaY * zoomSpeed;
    
    // 限制缩放范围
    const minDistance = 2;
    const maxDistance = 10;
    const clampedDistance = Math.max(minDistance, Math.min(maxDistance, newDistance));
    
    // 更新相机位置
    const direction = cameraRef.current.position.clone().normalize();
    cameraRef.current.position.copy(direction.multiplyScalar(clampedDistance));
  };

  // 处理鼠标释放
  const handleMouseUp = (event: MouseEvent) => {
    if (!isDragging) return;
    
    setIsDragging(false);
    const dx = event.clientX - dragStart.x;
    const dy = event.clientY - dragStart.y;
    const dist = Math.sqrt(dx*dx + dy*dy);
    if (dist > DRAG_CLICK_BUFFER) {
      // 拖动，不触发 click/选区
      return;
    }
    
    // 如果不是拖动，则处理点击事件
    handleMouseClick(event);
  };

  // 处理鼠标点击
  const handleMouseClick = (event: MouseEvent) => {
    if (!containerRef.current || !cameraRef.current || !rendererRef.current) return;

    const rect = containerRef.current.getBoundingClientRect();
    mouseRef.current.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    mouseRef.current.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

    raycasterRef.current.setFromCamera(mouseRef.current, cameraRef.current);
    
    // 检测标记点击
    if (markersRef.current) {
      const intersects = raycasterRef.current.intersectObjects(markersRef.current.children, true);
      if (intersects.length > 0) {
        const marker = intersects[0].object;
        const userData = marker.userData;
        if (userData.type === 'location') {
          onLocationClick?.(userData.data);
          return;
        } else if (userData.type === 'detection') {
          onDetectionPointClick?.(userData.data);
          return;
        }
      }
    }

    // 选区模式：meta键或模拟Meta键
    const selectionMode = event.metaKey || simulatedMetaKey;
    if (selectionMode) {
      const hit = getMouseLatLng(event);
      if (hit) {
        if (selectionClickCount === 0) {
          setSelectionPoints([hit, hit]);
          setSelectionClickCount(1);
          // renderSelection() 会通过useEffect自动调用
        } else if (selectionClickCount === 1 && selectionPoints) {
          const finalSelectionPoints: [LatLngPoint, LatLngPoint] = [selectionPoints[0], hit];
          setSelectionPoints(finalSelectionPoints);
          setSelectionClickCount(0);
          // renderSelection() 会通过useEffect自动调用
          // 选区结束时回调
          if (onSelectionEnd) {
            const [start, end] = finalSelectionPoints;
            const lngRange = getCorrectLngRange(start.lng, end.lng);
            const selectionRect: LatLngRect = {
              minLat: Math.min(start.lat, end.lat),
              maxLat: Math.max(start.lat, end.lat),
              minLng: lngRange.minLng,
              maxLng: lngRange.maxLng
            };
            
            // 查找与选区相交的rects
            const intersectingRects = locationPoints.map(location => {
              const lngRange = getCorrectLngRange(location.left_longitude, location.right_longitude);
              return {
                minLat: Math.min(location.left_latitude, location.right_latitude),
                maxLat: Math.max(location.left_latitude, location.right_latitude),
                minLng: lngRange.minLng,
                maxLng: lngRange.maxLng
              };
            }).filter(rect => rectIntersects(rect, selectionRect));
            
            // 查找与选区相交的探测点
            const intersectingDetectionPoints = detectionPoints.filter(point => {
              return pointIntersectsRect(
                { lat: point.center_latitude, lng: point.center_longitude }, 
                selectionRect
              );
            });
            
            onSelectionEnd(selectionRect, intersectingRects, intersectingDetectionPoints);
          }
        }
        return;
      }
    }

    // 检测模型点击
    if (modelRef.current && cameraRef.current && rendererRef.current) {
      const hit = getMouseRaycastForModel(event, cameraRef.current, rendererRef.current, modelRef.current.children[0]);
      if (hit) {
        onClick?.({ lat: hit.lat, lng: hit.lng });
      }
    }
  };


  // 渲染循环
  const animate = () => {
    requestAnimationFrame(animate);
    
    // 惯性动画
    if (!isDragging && modelRef.current) {
      const base = 0.008;
      const z = cameraRef.current?.position.z || 3;
      let sensitivity = base * (z - 1);
      sensitivity = Math.max(sensitivity, 0.0008);
      modelRef.current.rotation.y += inertia.vx * sensitivity * 16;
      modelRef.current.rotation.x = Math.max(-Math.PI/2, Math.min(Math.PI/2, modelRef.current.rotation.x + inertia.vy * sensitivity * 16));
      setInertia(prev => ({
        vx: prev.vx * 0.92,
        vy: prev.vy * 0.92
      }));
      if (Math.abs(inertia.vx) < 0.001) { setInertia(prev => ({ ...prev, vx: 0 })); }
      if (Math.abs(inertia.vy) < 0.001) { setInertia(prev => ({ ...prev, vy: 0 })); }
    }
    
    
    if (rendererRef.current && sceneRef.current && cameraRef.current) {
      rendererRef.current.render(sceneRef.current, cameraRef.current);
    }
  };

  // 处理窗口大小变化
  const handleResize = () => {
    if (!containerRef.current || !cameraRef.current || !rendererRef.current) return;

    const container = containerRef.current;
    const width = container.clientWidth || window.innerWidth;
    const height = container.clientHeight || window.innerHeight || 400;

    cameraRef.current.aspect = width / height;
    cameraRef.current.updateProjectionMatrix();
    rendererRef.current.setSize(width, height);
  };

  // 初始化
  useEffect(() => {
    // 延迟初始化，确保DOM完全渲染
    const timer = setTimeout(() => {
      initScene();
      loadModel();
    }, 100);

    return () => {
      clearTimeout(timer);
      // 清理焦点标记
      if (focusMarker && markersRef.current) {
        markersRef.current.remove(focusMarker);
        focusMarker.geometry.dispose();
        if (Array.isArray(focusMarker.material)) {
          focusMarker.material.forEach((m: any) => m.dispose());
        } else {
          focusMarker.material.dispose();
        }
      }
      // 清理黄色标记
      if (yellowMarker && markersRef.current) {
        markersRef.current.remove(yellowMarker);
        yellowMarker.geometry.dispose();
        if (Array.isArray(yellowMarker.material)) {
          yellowMarker.material.forEach((m: any) => m.dispose());
        } else {
          yellowMarker.material.dispose();
        }
      }
      if (rendererRef.current && containerRef.current) {
        containerRef.current.removeChild(rendererRef.current.domElement);
      }
      if (rendererRef.current) {
        rendererRef.current.dispose();
      }
    };
  }, [modelUrl, radius]);

  // 添加事件监听器
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    container.addEventListener('mousedown', handleMouseDown);
    container.addEventListener('mousemove', handleMouseMove);
    container.addEventListener('mouseup', handleMouseUp);
    container.addEventListener('wheel', handleWheel, { passive: false });
    window.addEventListener('resize', handleResize);

    return () => {
      container.removeEventListener('mousedown', handleMouseDown);
      container.removeEventListener('mousemove', handleMouseMove);
      container.removeEventListener('mouseup', handleMouseUp);
      container.removeEventListener('wheel', handleWheel);
      window.removeEventListener('resize', handleResize);
    };
  }, [simulatedMetaKey, selectionPoints, selectionClickCount, isDragging, hasDragged, lastMouse, lastRotation, dragStart, inertia, lastMove]);

  // 更新标记
  useEffect(() => {
    createLocationMarkers();
  }, [locationPoints, detectionPoints, radius]);

  // 更新焦点标记
  useEffect(() => {
    updateFocusMarker(hoverFocus);
  }, [hoverFocus]);

  // 更新黄色hover标记
  useEffect(() => {
    updateYellowMarker(yellowHoverPoint);
  }, [yellowHoverPoint]);


  // 响应外部选区变化
  useEffect(() => {
    if (externalSelection) {
      // 将LatLngRect转换为两个点
      // const point1: LatLngPoint = { lat: externalSelection.minLat, lng: externalSelection.minLng };
      // const point2: LatLngPoint = { lat: externalSelection.maxLat, lng: externalSelection.maxLng };
      // setSelectionPoints([point1, point2]);
      // renderSelection() 会通过selectionPoints的useEffect自动调用
    } else {
      // 清除选区
      // setSelectionPoints(null);
      // clearSelectionLine() 会通过selectionPoints的useEffect自动调用
    }
  }, [externalSelection]);

  // 监听selectionPoints变化，自动重新渲染选区
  useEffect(() => {
    if (selectionPoints) {
      renderSelection();
    } else {
      clearSelectionLine();
    }
  }, [selectionPoints]);

  // 开始渲染循环
  useEffect(() => {
    animate();
  }, []);

  return (
    <div className="earth-3d-container" style={{ width: '100%', height: '100%' }}>
      <div 
        ref={containerRef} 
        className="earth-3d-canvas"
        style={{ 
          width: '100%', 
          height: '100%',
          position: 'relative',
          cursor: simulatedMetaKey ? 'crosshair' : (isDragging ? 'grabbing' : 'grab'),
          minHeight: '400px'
        }}
      />
      
      {isLoading && (
        <div className="loading-overlay">
          <div className="loading-spinner">
            <div className="spinner"></div>
            <div className="loading-text">正在加载3D模型...</div>
          </div>
        </div>
      )}
      
      {error && (
        <div className="error-overlay">
          <div className="error-message">
            <div className="error-icon">⚠️</div>
            <div className="error-text">{error}</div>
            <button 
              className="retry-button"
              onClick={() => window.location.reload()}
            >
              重试
            </button>
          </div>
        </div>
      )}
    </div>
  );
});

GLBRenderer.displayName = 'GLBRenderer';

export default GLBRenderer;
